import { ref, onUnmounted, watch } from 'vue'
import { message } from 'ant-design-vue'
import { useUserStore } from '@/stores/user'

// 消息类型
export type PictureEditMessageType = 'INFO' | 'ERROR' | 'ENTER_EDIT' | 'EXIT_EDIT' | 'EDIT_ACTION'

// 编辑动作类型
export type PictureEditActionType = 'ROTATE_LEFT' | 'ROTATE_RIGHT' | 'ZOOM_IN' | 'ZOOM_OUT'

// 请求消息
export interface PictureEditRequestMessage {
  type: PictureEditMessageType
  editAction?: PictureEditActionType
}

// 响应消息
export interface PictureEditResponseMessage {
  type: PictureEditMessageType
  message: string
  editAction?: PictureEditActionType
  user?: {
    id: string
    userName: string
    userAvatar?: string
  }
}

// 在线用户
export interface OnlineUser {
  id: string
  userName: string
  userAvatar?: string
  isEditing: boolean // 是否正在编辑
}

export function usePictureEditWebSocket(pictureId: string) {
  const userStore = useUserStore()
  const ws = ref<WebSocket | null>(null)
  const isConnected = ref(false)
  const isConnecting = ref(false)
  const messages = ref<PictureEditResponseMessage[]>([])
  const onlineUsers = ref<Map<string, OnlineUser>>(new Map())
  const currentEditor = ref<OnlineUser | null>(null) // 当前正在编辑的用户

  let heartbeatTimer: number | null = null
  let reconnectTimer: number | null = null
  let reconnectAttempts = 0
  const maxReconnectAttempts = 3

  // 连接WebSocket
  const connect = async () => {
    if (isConnected.value || isConnecting.value) {
      return
    }

    try {
      isConnecting.value = true
      console.log('正在建立图片编辑WebSocket连接...')

      // 构建WebSocket URL
      // 注意：路径是 /api/ws/picture/edit（包含 /api 前缀）
      // 后端从查询参数中获取pictureId
      const protocol = window.location.protocol === 'https:' ? 'wss:' : 'ws:'
      const host = window.location.host
      const wsUrl = `${protocol}//${host}/api/ws/picture/edit?pictureId=${pictureId}`

      console.log('5. 连接WebSocket URL:', wsUrl)
      console.log('6. 图片ID (字符串):', pictureId, 'type:', typeof pictureId)
      console.log('7. 当前环境:', import.meta.env.DEV ? '开发环境' : '生产环境')
      ws.value = new WebSocket(wsUrl)

      ws.value.onopen = () => {
        console.log('图片编辑WebSocket连接已建立')
        isConnected.value = true
        isConnecting.value = false
        reconnectAttempts = 0
        startHeartbeat()
        message.success('已加入协同编辑')
      }

      ws.value.onmessage = (event) => {
        try {
          const messageData: PictureEditResponseMessage = JSON.parse(event.data)
          handleMessage(messageData)
        } catch (error: unknown) {
          console.error('解析WebSocket消息失败:', error)
        }
      }

      ws.value.onclose = (event) => {
        console.log('图片编辑WebSocket连接已关闭:', event.code, event.reason)
        isConnected.value = false
        isConnecting.value = false
        stopHeartbeat()

        // 非正常关闭时尝试重连
        if (event.code !== 1000 && reconnectAttempts < maxReconnectAttempts) {
          const delay = Math.min(1000 * Math.pow(2, reconnectAttempts), 10000)
          console.log(`${delay / 1000}秒后尝试重连...`)
          reconnectTimer = window.setTimeout(() => {
            reconnectAttempts++
            connect()
          }, delay)
        }
      }

      ws.value.onerror = (error) => {
        console.error('图片编辑WebSocket错误:', error)
        isConnected.value = false
        isConnecting.value = false
      }
    } catch (error: unknown) {
      console.error('建立WebSocket连接失败:', error)
      isConnecting.value = false
      message.error('连接协同编辑服务失败')
      throw error
    }
  }

  // 处理WebSocket消息
  const handleMessage = (messageData: PictureEditResponseMessage) => {
    messages.value.push(messageData)

    // 保持消息列表不超过50条
    if (messages.value.length > 50) {
      messages.value = messages.value.slice(-50)
    }

    switch (messageData.type) {
      case 'INFO':
        console.log('信息:', messageData.message)
        // 用户加入或退出
        if (messageData.user) {
          if (messageData.message.includes('加入')) {
            onlineUsers.value.set(messageData.user.id, {
              ...messageData.user,
              isEditing: false,
            })
            message.info(messageData.message)
          } else if (messageData.message.includes('退出')) {
            onlineUsers.value.delete(messageData.user.id)
            message.info(messageData.message)
          }
        }
        break

      case 'ENTER_EDIT':
        console.log('用户开始编辑:', messageData.user?.userName)
        if (messageData.user) {
          const user = onlineUsers.value.get(messageData.user.id)
          if (user) {
            user.isEditing = true
            currentEditor.value = user
          } else {
            const newUser: OnlineUser = {
              ...messageData.user,
              isEditing: true,
            }
            onlineUsers.value.set(messageData.user.id, newUser)
            currentEditor.value = newUser
          }
          // 只在自己获得编辑权限时显示成功提示
          if (messageData.user.id === userStore.loginUser?.id?.toString()) {
            message.success('已获得编辑权限')
          } else {
            message.info(messageData.message)
          }
        }
        break

      case 'EXIT_EDIT':
        console.log('用户退出编辑:', messageData.user?.userName)
        if (messageData.user) {
          const user = onlineUsers.value.get(messageData.user.id)
          if (user) {
            user.isEditing = false
          }
          if (currentEditor.value?.id === messageData.user.id) {
            currentEditor.value = null
          }
          message.info(messageData.message)
        }
        break

      case 'EDIT_ACTION':
        console.log('编辑动作:', messageData.editAction, messageData.user?.userName)
        // 触发编辑动作事件，供组件监听
        if (messageData.editAction && messageData.user) {
          // 这个消息表示其他用户执行了编辑操作
          message.info(messageData.message)
        }
        break

      case 'ERROR':
        console.error('错误:', messageData.message)
        message.error(messageData.message)
        break

      default:
        console.log('收到未知类型的消息:', messageData)
    }
  }

  // 发送消息
  const sendMessage = (msg: PictureEditRequestMessage) => {
    if (ws.value && ws.value.readyState === WebSocket.OPEN) {
      ws.value.send(JSON.stringify(msg))
    } else {
      console.error('WebSocket未连接')
      message.error('连接已断开，请重新加入编辑')
    }
  }

  // 进入编辑状态
  // 返回 Promise 用于超时处理
  const enterEdit = (): Promise<boolean> => {
    return new Promise((resolve, reject) => {
      // 设置超时：2秒内未收到 ENTER_EDIT 响应则认为失败
      const timeoutId = setTimeout(() => {
        reject(new Error('抢占编辑锁超时，可能有其他用户正在编辑'))
      }, 2000)

      // 监听 ENTER_EDIT 响应
      const checkEnterEdit = () => {
        // 检查当前用户是否获得编辑权限
        if (isCurrentUserEditing()) {
          clearTimeout(timeoutId)
          resolve(true)
        }
      }

      // 临时监听状态变化
      const unwatch = watch(
        () => currentEditor.value,
        () => {
          checkEnterEdit()
          if (isCurrentUserEditing()) {
            unwatch()
          }
        },
      )

      // 发送请求
      sendMessage({
        type: 'ENTER_EDIT',
      })

      // 清理函数
      setTimeout(() => {
        unwatch()
      }, 2500)
    })
  }

  // 退出编辑状态
  const exitEdit = () => {
    sendMessage({
      type: 'EXIT_EDIT',
    })
  }

  // 执行编辑操作
  const executeEditAction = (action: PictureEditActionType) => {
    sendMessage({
      type: 'EDIT_ACTION',
      editAction: action,
    })
  }

  // 心跳机制
  const startHeartbeat = () => {
    heartbeatTimer = window.setInterval(() => {
      if (ws.value?.readyState === WebSocket.OPEN) {
        ws.value.send('ping')
      }
    }, 30000) // 30秒发送一次心跳
  }

  const stopHeartbeat = () => {
    if (heartbeatTimer) {
      clearInterval(heartbeatTimer)
      heartbeatTimer = null
    }
  }

  // 断开连接
  const disconnect = () => {
    if (reconnectTimer) {
      clearTimeout(reconnectTimer)
      reconnectTimer = null
    }
    if (ws.value) {
      ws.value.close(1000, '用户主动断开')
      ws.value = null
    }
    isConnected.value = false
    isConnecting.value = false
    stopHeartbeat()
    reconnectAttempts = 0
    onlineUsers.value.clear()
    currentEditor.value = null
    messages.value = []
  }

  // 获取最近的消息
  const getRecentMessages = (count = 10) => {
    return messages.value.slice(-count).reverse()
  }

  // 检查当前用户是否正在编辑
  const isCurrentUserEditing = () => {
    return currentEditor.value?.id === userStore.loginUser?.id?.toString()
  }

  // 组件卸载时断开连接
  onUnmounted(() => {
    disconnect()
  })

  return {
    // 状态
    isConnected,
    isConnecting,
    messages,
    onlineUsers,
    currentEditor,

    // 方法
    connect,
    disconnect,
    enterEdit,
    exitEdit,
    executeEditAction,
    getRecentMessages,
    isCurrentUserEditing,
  }
}
